// Copyright (C) Calum Grant 2008

namespace
{
	template<int N> struct msvc_bug_workaround;
}

// Essentially a s##__COUNTER__ bug workaround
#define static_call(X) \
	namespace { template<> struct msvc_bug_workaround<__LINE__> { static const bool dummy; }; } \
	const bool msvc_bug_workaround<__LINE__>::dummy=(X,true);


namespace dynamic
{
	/// Register a prototype object to instantiate when unpickling.
	DYNAMIC_API void register_pickle_type(var_cmp_index, const var&);

	/// Create an of a given object type.
	/** The type must previously have been registered by \ref register_pickle_type */
	DYNAMIC_API var unpickle_type(var_cmp_index);

	/// A helper class used by the \ref pickle() function to keep track of pickling.
	class pickler : cg::not_copyable, cg::not_assignable
	{
	public:
		/// Defines where the output should be written.
		pickler(std::ostream&);

		/// Writes the given object to the stream.
		/** This may decide to write a reference if the object has been written previously */
		void write_object(const var & o);

		/// Writes the object type to the stream.
		void write_object_type(var_cmp_index);

		/// Writes an integer to the stream.
		void write_int(int i);

		/// Writes a size to the stream.
		void write_size(std::size_t);

		/// Writes a double to the stream.
		void write_double(double d);

		/// Writes a string to the stream.
		void write_string(std::string const&);

	private:
		typedef std::map<shared_var_impl*, std::size_t> object_map;
		object_map m_objects;		///< Which objects we've written already.
		std::ostream & m_output;	///< Where to write the data.
	};
}
